#pragma once 

#include <iostream>
#include <string>
#include <cstring>
#include <arpa/inet.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>

class TcpClient{
  private:
    int sockfd;
    int server_port;
    std::string server_ip;
  public:
    TcpClient(std::string _ip, int _port):sockfd(-1), server_port(_port), server_ip(_ip)
    {}

    bool InitTcpClient()
    {
      int sockfd = socket(AF_INET, SOCK_STREAM, 0);
      if(sockfd == -1){
        std::cerr << "socket error" << std::endl;
        return false;
      }

      return true;
    }

    void Start()
    {
      struct sockaddr_in peer;
      memset(&peer, 0, sizeof(peer));
      peer.sin_family = AF_INET;
      peer.sin_port = htons(server_port);
      peer.sin_addr.s_addr = inet_addr(server_ip.c_str());
      socklen_t len = sizeof(peer);
      if(connect(sockfd, (struct sockaddr*)&peer, len) < 0){
        std::cerr << "connect error" << std::endl;
      } 
      else {
        std::cout << "connect succeed......" << std::endl;
        //Request(sockfd);
      }
    }

    void Request(int sockfd)
    {
      struct sockaddr_in peer;
      memset(&peer, 0, sizeof(peer));
      socklen_t len = sizeof(peer);
      std::string msg;

      std::cout << "Please Enter #" << std::endl;
      while(true){
        std::cin >> msg;

        ssize_t size = sendto(sockfd,msg.c_str(), msg.size(), 0, (struct sockaddr*)&peer, len);
        if(size == -1){
          std::cerr << "sendto error" << std::endl;
        }

        //回响
#define SIZE 128
        char buffer[SIZE];
        size = recvfrom(sockfd, buffer, sizeof(buffer) - 1, 0, (struct sockaddr*)&peer, &len);
        if(size == -1){
          std::cerr << "recvfrom error" << std::endl;
        }
        else if(size == 0){
          std::cout << "recvfrom the end of socket" << std::endl;
        }
        else{
          buffer[size] = 0;
          std::cout << "Server get->" << buffer << std::endl;
        }
      }
    }

    ~TcpClient()
    {
      if(sockfd != -1) close(sockfd);
    }
};
